# coding: utf-8

import random


class Header:
    pack_count: 0
    pack_index: 0
    pack_size: 0
    pack_type: 0
    flag: None

class Pack:
    def __init__(self):
        self.receive_data = []
        self.response_data=[]
        pass

    def add_response_data(self,header: Header,data):
        self.response_data.append({
                    "header": header,
                    "data": data
                })

    def get_response_data(self,header:Header):
        flag = header.flag
        resdata = ''.encode()
        count=0
        for item in self.response_data:
            if flag==item['header'].flag:
                count=item['header'].pack_count
                break
        for index in range(count):
            data = self.get_response_index_data(index + 1, flag)
            if data:
                resdata = resdata + data
            else:
                return None
        if resdata:
            return resdata
        else:
            return None

    def get_response_index_data(self,index,flag:bytes):
        data = None
        # print("response_data",self.response_data)
        for i in range(len(self.response_data)):
            if (self.response_data[i]["header"].flag == bytes(flag) and self.response_data[i]["header"].pack_index == index):
                response_data = self.response_data.pop(i)
                data = response_data["data"]
                break
        return data



    def add_receive_data(self,header: Header,data):
        self.response_data.append({
                    "index": header.pack_index,
                    "flag": header.flag,
                    "data": data
                })

    def get_receive_data(self, header: Header):
        flag = header.flag
        resdata = ''.encode()
        for index in range(header.pack_count - 1):
            data = self.get_recevie_index_data(index + 1, flag)
            if data:
                resdata = resdata + data
            else:
                return None
        if resdata:
            return resdata
        else:
            return None

    def get_recevie_index_data(self, index, flag: bytes):
        data = None
        for i in range(len(self.receive_data)):
            if (self.receive_data[i]["flag"] == flag and self.receive_data[i]["index"] == index):
                receive_data = self.receive_data.pop(i)
                data = receive_data["data"]
                break
        return data

    def pack_unpack(self, Buffer: bytes):
        '''
        解包
        :param Buffer: Buffer 二进制数据
        :return: 返回 包结构 和 数据二进制
        '''
        head_buffer = Buffer[0:16]
        header = self.pack_unhead(head_buffer)
        data = Buffer[16:]
        return header, data

    def pack_uppack(self, max_pack: int, Buffer: bytes,pack_type=0,flag:bytes=None):
        '''
        分包
        :param max_pack:最大包长度
        :param Buffer: 原始数据 bytearray
        :return: 返回 bytearray 列表
        '''
        ResBuffer = []
        buffer_len = len(Buffer)
        _max_pack = max_pack - 16
        head = Header()
        if(flag):
            head.flag=flag
        else:
            head.flag = self.get_header_flag()
        head.pack_type = pack_type
        if (buffer_len > _max_pack):
            leftover_Buffer = Buffer
            if (buffer_len % _max_pack == 0):
                head.pack_count = int(buffer_len / _max_pack)
            else:
                head.pack_count = int(buffer_len / _max_pack) + 1
            head.pack_index = 1
            while (head.pack_index <= head.pack_count and leftover_Buffer):
                if (len(leftover_Buffer) > _max_pack):
                    TBbuffer = leftover_Buffer[0:_max_pack]
                    leftover_Buffer = leftover_Buffer[_max_pack:]
                else:
                    TBbuffer = leftover_Buffer
                    leftover_Buffer = None
                head.pack_size = len(TBbuffer)
                headBuffer = self.pack_uphead(head)
                ResBuffer.append(headBuffer + TBbuffer)
                head.pack_index = head.pack_index + 1
        else:
            head.pack_count = 1
            head.pack_index = 1
            head.pack_size = buffer_len
            headBuffer = self.pack_uphead(head)
            ResBuffer.append(headBuffer + Buffer)
        return head,ResBuffer

    def get_header_flag(self):
        '''
        生成包头标记
        :return: 返回 bytearray
        '''
        f = []
        for i in range(12):
            f.append(random.randint(0, 255))
        return (bytearray(f))

    def pack_unhead(self, header_buffer: bytes):
        '''
        取包头
        :param header_buffer: 包头二进制
        :return: Header结构
        '''
        header = Header()
        header.pack_count = header_buffer[0]
        header.pack_index = header_buffer[1]
        header.pack_size = header_buffer[2]
        header.pack_type = header_buffer[3]
        header.flag = header_buffer[4:]
        return header

    def pack_uphead(self, header: Header):
        '''
        生成包头
        :param header: 包头结构
        :return: 返回 bytearray
        '''
        Buffer = bytes([header.pack_count, header.pack_index, header.pack_size, header.pack_type])
        return Buffer + header.flag
